package de.bht.fb6.cg1.exercise1;

import java.awt.Color;

/**
 * implements YUV color space.
 * 
 * @author Dominik Eckelmann
 */
public class YUV extends AbstractColorModel {

    /**
     * creates a new YUV object.
     * 
     * @param c initial color.
     */
    public YUV(final Color c) {
        super(c);
    }

    /**
     * converts a {@link Color} Object into the YUV values
     * 
     * the formula is taken from http://www.fourcc.org/fccyvrgb.php
     * 
     * @param c     color object to set.
     * @return new YUV color components.
     */
    @Override
    public int[] setColor(final Color c) {

        modelColor[0] = (int) ((0.257f * c.getRed()) + (0.504f * c.getGreen()) + (0.098f * c.getBlue()) + 16);
        modelColor[1] = (int) ((0.439f * c.getRed()) - (0.368f * c.getGreen()) - (0.071f * c.getBlue()) + 128);
        modelColor[2] = (int) (-(0.148f * c.getRed()) - (0.291f * c.getGreen()) + (0.439f * c.getBlue()) + 128);

        color = c;
        return modelColor;
    }

    /**
     * sets a new color by yuv components array.
     * 
     * the formula is taken from http://www.fourcc.org/fccyvrgb.php
     * 
     * @param color the new color.
     * @return the new translated color
     */
    @Override
    public Color setModelColor(final int[] color) {
        int r;
        int g;
        int b;

        if (color.length != getComponentCount()) {
            throw new IllegalArgumentException();
        }

        b = clip(1.164f * (color[0] - 16) + 2.018f * (color[1] - 128));
        g = clip(1.164f * (color[0] - 16) - 0.813f * (color[2] - 128) - 0.391f * (color[1] - 128));
        r = clip(1.164f * (color[0] - 16) + 1.596f * (color[2] - 128));

        this.color = new Color(r, g, b);
        modelColor = color;
        return this.color;
    }

    /**
     * YUV color space name.
     * 
     * @return name.
     */
    @Override
    public String getName() {
        return "YUV";
    }

    /**
     * get the number of components
     * 
     * @return usualy 3
     */
    @Override
    public int getComponentCount() {
        return 3;
    }

    /**
     * returns the range for every single component
     * @return range informations
     */
    @Override
    public Range[] getComponentRange() {
        final Range ranges[] = new Range[] {
                new Range(16,235), new Range(16,239), new Range(16,239)
        };
        return ranges;
    }
}
